/*
 * Copyright 2022 Rich yang, 18158898020@189.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */


`include "defines.v"

module data_ram(
	input wire			clk,
	input wire			ce,
	input wire			we,
	input wire[`DataAddrBus]	addr,
	input wire[3:0]			sel,
	input wire[`DataBus]		data_i,
	output reg[`DataBus]		data_o
);

	reg[`ByteWidth] data_mem0[0:`DataMemNum-1];
	reg[`ByteWidth] data_mem1[0:`DataMemNum-1];
	reg[`ByteWidth] data_mem2[0:`DataMemNum-1];
	reg[`ByteWidth] data_mem3[0:`DataMemNum-1];

	initial $readmemh("data_ram0.data", data_mem0);
	initial $readmemh("data_ram1.data", data_mem1);
	initial $readmemh("data_ram2.data", data_mem2);
	initial $readmemh("data_ram3.data", data_mem3);

	always @ (posedge clk) begin
		if (ce == `ChipDisable) begin

		end else if (we == `WriteEnable) begin
			if (sel[3] == 1'b1) begin

				data_mem3[addr[`DataMemNumLog2+1:2]] <= data_i[31:24];
			end
			if (sel[2] == 1'b1) begin
				data_mem2[addr[`DataMemNumLog2+1:2]] <= data_i[23:16];
			end
			if (sel[1] == 1'b1) begin
				data_mem1[addr[`DataMemNumLog2+1:2]] <= data_i[15:8];
			end
			if (sel[0] == 1'b1) begin
				data_mem0[addr[`DataMemNumLog2+1:2]] <= data_i[7:0];
			end
		end
	end


	always @ (*) begin
		if (ce == `ChipDisable) begin
			data_o <= `ZeroWord;
		end else if (we == `WriteDisable) begin
			data_o <= {data_mem3[addr[`DataMemNumLog2+1:2]],
				   data_mem2[addr[`DataMemNumLog2+1:2]],
				   data_mem1[addr[`DataMemNumLog2+1:2]],
				   data_mem0[addr[`DataMemNumLog2+1:2]]};
		end else begin
			data_o <= `ZeroWord;
		end
	end

endmodule
